package com.piaoniu.pndao.utils;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * SqlBuilder
 *
 * @author T_T
 * @since 09/12/2016 23:14
 */
public class SqlBuilder {

    String columnStyle = "underline";

    StringBuilder sql = new StringBuilder(50);

    String table;

    List<ObjField> columns = new LinkedList<>();

    List<ObjField> conditions = new LinkedList<>();

    List<ObjField> orderBys = new LinkedList<>();

    public SqlBuilder(String table) {
        this.table = table;
    }

    public SqlBuilder addColumns(List<ObjField> columns) {
        this.columns.addAll(columns);
        return this;
    }

    public SqlBuilder addSelectColumn(ObjField columns) {
        this.columns.add(columns);
        return this;
    }

    public SqlBuilder addWhereCondition(ObjField conditions) {
        this.conditions.add(conditions);
        return this;
    }

    public SqlBuilder addWhereConditions(List<ObjField> conditions) {
        this.conditions.addAll(conditions.stream().collect(Collectors.toList()));
        return this;
    }

    public SqlBuilder orderBy(ObjField orderBy) {
        orderBys.add(orderBy);
        return this;
    }

    void append(String snippet) {
        if (snippet != null) {
            sql.append(snippet).append(" ");
        }
    }

    void appends(List<ObjField> snippets) {
        append(StringHelper.joinWithComma(snippets.iterator()));
    }

    void appendColumns(List<ObjField> snippets) {
        append(StringHelper.joinWithComma(snippets.stream().iterator()));
    }

    public String sql() {
        append("SELECT");
        appendColumns(columns);
        append("FROM");
        append(table);

        append("WHERE");
        appends(conditions);
        append("ORDER BY");
        appends(orderBys);
        return sql.toString();
    }

    public static String express(String field) {
        return "#{" + field + "}";
    }

    public static String eqExpress(String field, String style) {
        return StringHelper.toColumnByStyle(field, style) + " = " + express(field);
    }

    public static String column(String field, String style) {
        return StringHelper.toColumnByStyle(field, style) + " AS " + field;
    }

    public static String conditionExpress(String field, String operator, String style) {

        return StringHelper.toColumnByStyle(field, style) + " " + operator + " " + express(field);//id >= #{id}
    }

    public static void main(String[] args) {
        final String sql1 = new SELECT("t_user")
                .addSelectColumn(ObjField.snippet("count(1)"))
                .addWhereConditions(Collections.singletonList(ObjField.condition("UserName")))
                .orderBy(ObjField.order("id"))
                .sql();
        System.out.println(sql1);
    }
}

class SELECT extends SqlBuilder {

    public SELECT(String table) {
        super(table);
    }

    @Override
    public String sql() {
        append("SELECT");
        appendColumns(columns);
        append("FROM");
        append(table);

        if (conditions.size() > 0) {
            append("WHERE");
            appendsConditions(conditions);
        }

        append("ORDER BY");
        appends(orderBys);
        return sql.toString();
    }

    private void appendsConditions(List<ObjField> conditions) {
        //TODO optimisation
        append(StringHelper.joinWithComma(
                conditions.stream()
                        .iterator()));
    }
}